home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 10
/
FM Towns Free Software Collection 10.iso
/
ms_dos
/
tool
/
fwcp
/
src
/
menu.c
< prev
next >
Wrap
Text File
|
1995-03-15
|
7KB
|
322 lines
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
#ifdef MSDOS
#include <jctype.h>
#endif
#include "defs.h"
#include "key.h"
void wind(int sx, int sy, int wd, int ht)
{
int n, i;
#ifdef MSDOS
sx -= 1;
sy -= 1;
LOCATE(sx, sy++);
PUTANK(0x9C);
for ( n = 0 ; n < wd ; n++ )
PUTANK(0x95);
PUTANK(0x9D);
for ( i = 0 ; i < ht ; i++ ) {
LOCATE(sx, sy++);
PUTANK(0x96);
for ( n = 0 ; n < wd ; n++ )
PUTANK(' ');
PUTANK(0x96);
}
LOCATE(sx, sy++);
PUTANK(0x9E);
for ( n = 0 ; n < wd ; n++ )
PUTANK(0x95);
PUTANK(0x9F);
#else
sx -= 2;
sy -= 1;
LOCATE(sx, sy++);
PUTS("┌");
for ( n = 0 ; n < wd ; n += 2 )
PUTS("─");
PUTS("┐");
for ( i = 0 ; i < ht ; i++ ) {
LOCATE(sx, sy++);
PUTS("│");
for ( n = 0 ; n < wd ; n += 2 )
PUTS(" ");
PUTS("│");
}
LOCATE(sx, sy++);
PUTS("└");
for ( n = 0 ; n < wd ; n += 2 )
PUTS("─");
PUTS("┘");
#endif
}
int hash_menu(int x, int y, int len, char *arg[])
{
int i, n;
int ent = 0;
int max = 16;
int ext = 1;
char **av;
short *nv;
char tmp[36];
char *p;
if ( (av = (char **)malloc(sizeof(char *) * max)) == NULL )
return ERR;
if ( len >= 32 )
len = 32;
LOOP:
for ( n = 0 ; arg[n] != NULL ; n++ ) {
strncpy(tmp, arg[n], len);
tmp[len] = '\0';
for ( p = tmp ; *p != '\0' ; ) {
if ( iskanji(p[0]) ) {
if ( !iskanji2(p[1]) )
break;
p += 2;
} else
p++;
}
*p = '\0';
for ( i = 0 ; i < ent ; i++ ) {
if ( strcmp(av[i], tmp) == 0 )
break;
}
if ( ent > 0 && i < ent )
continue;
av[ent++] = strdup(tmp);
if ( ent >= max ) {
max += 32;
if ( (av = (char **)realloc(av, sizeof(char *) * max)) == NULL )
return ERR;
}
}
av[ent] = NULL;
if ( n == ent ) {
for ( n = 0 ; n < ent ; n++ )
free(av[n]);
free(av);
return menu(x, y, 0, arg);
} else if ( ent <= 1 ) {
for ( n = 0 ; n < ent ; n++ )
free(av[n]);
ent = 0;
if ( len >= 16 )
return menu(x, y, 0, arg);
len += 2;
goto LOOP;
} else if ( (n = menu(x, y, 0, av)) < 0 ) {
for ( n = 0 ; n < ent ; n++ )
free(av[n]);
free(av);
return ERR;
}
strcpy(tmp, av[n]);
len = strlen(tmp);
for ( n = 0 ; n < ent ; n++ )
free(av[n]);
ent = 0;
if ( (nv = (short *)malloc(sizeof(short) * max)) == NULL )
return ERR;
for ( n = 0 ; arg[n] != NULL ; n++ ) {
if ( strncmp(arg[n], tmp, len) != 0 )
continue;
nv[ent] = n;
av[ent++] = arg[n];
if ( ent >= max ) {
max += 32;
if ( (av = (char **)realloc(av, sizeof(char *) * max)) == NULL ||
(nv = (short *)realloc(nv, sizeof(short) * max)) == NULL )
return ERR;
}
}
av[ent] = NULL;
if ( ent >= 20 ) {
if ( (n = hash_menu(x + 4, y + 1, len + 2, av)) >= 0 )
n = nv[n];
} else if ( (n = menu(x + 4, y + 1 , 0, av)) >= 0 )
n = nv[n];
free(nv);
free(av);
return n;
}
int menu(int x, int y, int no, char *arg[])
{
int i, n, r, ch;
int len, max, mid, btm;
int od;
int rc = FALSE;
char form[64];
static int top = 0;
for ( len = max = 0 ; arg[max] != NULL ; max++ ) {
if ( (i = strlen(arg[max])) > len )
len = i;
}
if ( (y + max + 1) >= SCR_Y )
btm = SCR_Y - y - 1;
else
btm = max;
if ( (x + len) > (SCR_X - 2) ) {
if ( (x = SCR_X - 2 - len) < 2 )
x = 2;
if ( (x + len) > (SCR_X - 2) )
len = (SCR_X - 2 - x);
}
if ( max > btm && (len * 2 + 2) < (SCR_X - 4) ) {
mid = (max + btm - 1) / btm;
if ( ((len + 1) * mid) > (SCR_X - 4) )
mid = (SCR_X - 4) / (len + 1);
if ( (x + (len + 1) * mid) > (SCR_X - 2) )
x = SCR_X - 2 - (len + 1) * mid;
} else
mid = 1;
sprintf(form, "%%-%d.%ds", len, len);
CUROFF();
ACTCOL();
wind(x, y, (mid > 1 ? ((len + 1) * mid) : len), btm);
STDCOL();
if ( no <= 0 )
no = top = 0;
else if ( max == btm || top >= max )
top = 0;
else
top = (top / btm) * btm;
od = (-1);
while ( rc == FALSE ) {
if ( od != no ) {
if ( od < 0 || no < top || no >= (top + (btm * mid)) ) {
while ( no < top )
top -= btm;
while ( no >= (top + (btm * mid)) )
top += btm;
for ( n = 0 ; n < mid ; n++ ) {
for ( i = 0 ; i < btm ; i++ ) {
LOCATE(x + (len + 1) * n, y + i);
r = i + btm * n + top;
if ( r == no )
REVCOL();
if ( r >= max )
REPCHR(' ', len);
else
FPUTS(form, arg[r]);
if ( r == no )
NOMCOL();
}
}
} else {
LOCATE(x + (len + 1) * ((od - top) / btm),
y + (od - top) % btm);
FPUTS(form, arg[od]);
LOCATE(x + (len + 1) * ((no - top) / btm),
y + (no - top) % btm);
REVCOL();
FPUTS(form, arg[no]);
NOMCOL();
}
LOCATE(x + (len + 1) * ((no - top) / btm) + len,
y + (no - top) % btm);
FLUSH();
od = no;
}
ch = GETCH();
switch(ch) {
case K_UP_NODE:
case K_BACK_SPC:
case 0x1E:
case 0x08:
if ( --no < 0 )
no = max - 1;
break;
case K_DOWN_NODE:
case 0x1F:
case 0x20:
if ( ++no >= max )
no = 0;
break;
case K_RIGHT_CUR:
case 0x1D:
if ( mid < 2 )
break;
if ( (no -= btm) < 0 ) {
if ( (no = (max / btm) * btm + (no + btm)) >= max )
no -= btm;
}
break;
case K_LEFT_CUR:
case 0x1C:
if ( mid < 2 )
break;
if ( (no += btm) >= max )
no %= btm;
break;
case K_END_LINE:
case 0x0D:
rc = TRUE;
break;
case K_ABORT:
case 0x1B:
rc = ERR;
break;
default:
if ( (ch & 0xFF00) != 0 )
rc = ERR;
else {
for ( i = 0 ; i < max ; i++ ) {
if ( toupper(ch) == *arg[i] ) {
no = i;
rc = TRUE;
}
}
}
break;
}
}
CURON();
return (rc == TRUE ? no : (-1));
}